package Day_0201.JUC;

/**
 * @author zxc
 * @date 2023/02/01 17:15
 **/
public class Lock_optimization {
    public static void main(String[] args) {
        /**
         * 锁优化机制详述 :
         * ===>
         * 优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。
         *
         * 锁的状态从低到高依次为无锁->偏向锁->轻量级锁->重量级锁，
         * 升级的过程就是从低到高，降级在一定条件也是有可能发生的。
         *
         * 1.自旋锁：
         * （1）由于大部分时候，锁被占用的时间很短，共享变量的锁定时间也很短，所有没有必要挂起线程，用户态和内核态的来回上下文切换严重影响性能。
         * （2）自旋的概念就是让线程执行一个忙循环，可以理解为就是啥也不干，防止从用户态转入内核态，
         * （3）自旋锁可以通过设置-XX:+UseSpining来开启，自旋的默认次数是10次，可以使用-XX:PreBlockSpin设置。
         * ===》 即，自旋锁使得 未获取到对象锁的线程没必要挂起（防止用户态和内核态之间频繁的上下文切换，影响性能;）
         *
         * 2.自适应锁：
         * 自适应锁就是自适应的自旋锁，自旋的时间不是固定时间，而是由前一次在同一个锁上的自旋时间和锁的持有者状态来决定。
         * ===》 即，自适应锁就是自旋时间不固定的自旋锁;
         *
         * 3.锁消除：
         * 锁消除指的是JVM检测到一些同步的代码块，完全不存在数据竞争的场景，也就是不需要加锁，就会进行锁消除。
         *
         * 4.锁粗化：
         * 锁粗化指的是有很多操作都是对同一个对象进行加锁，就会把锁的同步范围扩展到整个操作序列之外。
         *
         * 5.偏向锁：
         * （1）当线程访问同步块获取锁时，会在对象头和栈帧中的锁记录里存储偏向锁的线程ID，
         *  之后这个线程再次进入同步块时都不需要CAS来加锁和解锁了，偏向锁会永远偏向第一个获得锁的线程，
         * （2）如果后续没有其他线程获得过这个锁，持有锁的线程就永远不需要进行同步，
         * （3）反之，当有其他线程竞争偏向锁时，持有偏向锁的线程就会释放偏向锁。
         * （4）可以用过设置-XX:+UseBiasedLocking开启偏向锁。
         * ===》 即，偏向锁指向第一个获取锁的线程ID，后续该线程进入同步代码块时，甚至不需要通过CAS操作去获取对象锁;
         *
         * 6.轻量级锁：
         * （1）JVM的对象的对象头中包含有一些锁的标志位，
         * （2）代码进入同步块的时候，JVM将会使用CAS方式来尝试获取锁，
         *  a.如果更新成功则会把对象头中的状态位标记为轻量级锁，
         *  b.如果更新失败，当前线程就尝试自旋来获得锁。
         * ===》 即，轻量级锁是通过CAS操作 && 自旋方式，来获取锁;
         *
         * ===》
         * 总结 ：
         * （1）偏向锁就是通过对象头的偏向线程ID来对比，甚至都不需要CAS了，
         * （2）而轻量级锁主要就是通过CAS修改对象头锁记录和自旋来实现，
         * （3）重量级锁则是除了拥有锁的线程其他全部阻塞。
         * ===》 即，重量级锁会阻塞除了获取对象锁的线程之外的所有线程;
         */
    }
}
